{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 如何利用通义千问查询阿里云资源\n",
    "\n",
    "作为阿里云开发者，我们常常需要查询阿里云上的资源信息，比如ECS、RDS等资源详情或产品说明。以往我们只能在官网上按步骤一页一页找到控制中心，再查到资源页面，节奏略显拖沓。如今，我们已经进入大模型时代，有什么办法可以更简便快捷的获取这些信息呢？能不能让大模型来做这件事？于是，基于LangChain的Agent架构，我们尝试制作了一个实现上述想法的大模型Agent，让大模型可以协助您查询您在阿里云上开通了哪些资源。您可以进入Jupyter Notebook环境来运行本章的代码，查询您在阿里云的资源使用情况，也可以将代码加入到您的工程项目中，利用[阿里云控制API](https://api.aliyun.com/product/cloudcontrol?tab=apis)实现更多功能，我们欢迎您将实验结果分享出来。\n",
    "\n",
    "本文我们将使用灵积API调用通义千问大模型，并利用[阿里云控制API](https://api.aliyun.com/product/cloudcontrol?tab=apis)来查询您的阿里云资源。\n",
    "\n",
    "## 学习之前\n",
    "- 本文假设你已经初步了解并使用过 python、git，因此不会涉及如何安装 [python](https://www.python.org/downloads/)、pip、[git](https://git-scm.com/) 等基础工具。\n",
    "- 本文侧重于如何将大模型 API 应用到工作中，因此并不不会详细介绍大模型以及机器学习的基础概念。\n",
    "\n",
    "\n",
    "## 1. 准备工作\n",
    "### 1.1. 环境配置\n",
    "在开始本文的学习之前，你可以先安装一下必要的依赖，以便运行相关代码：\n",
    "```bash\n",
    "pip install dashscope==1.13.6\n",
    "pip install langchain==0.1.0\n",
    "pip install langchainhub==0.1.14\n",
    "pip install langchain-experimental==0.0.49\n",
    "pip install beautifulsoup4==4.12.2\n",
    "pip install html2text==2020.1.16\n",
    "pip install alibabacloud_cloudcontrol20220830==1.1.0\n",
    "```\n",
    "\n",
    "\n",
    "### 1.2. 账号准备\n",
    "\n",
    "首先，您需要前往 [官网创建 API Key](https://help.aliyun.com/zh/dashscope/developer-reference/activate-dashscope-and-create-an-api-key)。接下来，请获取你的 [DASHSCOPE_API_KEY](https://dashscope.console.aliyun.com/apiKey)，您可以使用以下命令行导入系统，请于[RAM访问控制](https://ram.console.aliyun.com/manage/ak)查询和创建您的阿里云AK/SK\n",
    "\n",
    "####  MacOS or Linux\n",
    "您可以使用以下命令行导入环境变量\n",
    "```bash\n",
    "export DASHSCOPE_API_KEY=\"sk-****\"\n",
    "export ALIBABA_CLOUD_ACCESS_KEY_ID=\"<your access key id>\"\n",
    "export ALIBABA_CLOUD_ACCESS_KEY_SECRET=\"<your access key secret>\"\n",
    "```\n",
    "\n",
    "#### Windows\n",
    "可以在终端使用[`SET`](https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/set_1)命令设置环境变量\n",
    "```bat\n",
    "set DASHSCOPE_API_KEY=sk-****\n",
    "set ALIBABA_CLOUD_ACCESS_KEY_ID=your access key id\n",
    "set ALIBABA_CLOUD_ACCESS_KEY_SECRET=your access key secret\n",
    "```\n",
    "或者在[`PowerShell`](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-7.4)中使用以下命令行配置环境变量 \n",
    "```powershell\n",
    "$Env:DASHSCOPE_API_KEY = \"sk-****\"\n",
    "$Env:ALIBABA_CLOUD_ACCESS_KEY_ID = \"<your access key id>\"\n",
    "$Env:ALIBABA_CLOUD_ACCESS_KEY_SECRET = \"<your access key secret>\"\n",
    "```\n",
    "\n",
    "#### Jupyter Notebook\n",
    "您可以使用[`os.environ`](https://docs.python.org/3/library/os.html)方法，在代码开头设置临时环境变量。\n",
    "\n",
    "### 1.3. docenv模式\n",
    "\n",
    "将环境变量写入文件\"~/.zshrc\"中：\n",
    "\n",
    "```bash\n",
    "export OPENAI_API_KEY=\"sk-...\"\n",
    "```\n",
    "就可以执行如下命令 ```source ~/.zshrc``` 将这个环境变量绑定到全局shell中。\n",
    "\n",
    "接下来我们将加载这个环境变量到notebook中。执行如下命令\n",
    "\n",
    "**使用Windows，已经通过Windows PowerShell来注册环境变量的同事可以考虑跳过这里**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Python-dotenv could not parse statement starting at line 5\n",
      "Python-dotenv could not parse statement starting at line 6\n",
      "Python-dotenv could not parse statement starting at line 8\n",
      "Python-dotenv could not parse statement starting at line 9\n",
      "Python-dotenv could not parse statement starting at line 14\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "## for MacOS users\n",
    "filePath = os.path.abspath(os.path.expanduser(os.path.expandvars(\"~/.zshrc\")))\n",
    "load_dotenv(filePath)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 搭建云资源查询AGENT\n",
    "\n",
    "### 2.1. 创建阿里云资源查询API工具"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 阿里云资源查询工具\n",
    "\n",
    "# -*- coding: utf-8 -*-\n",
    "import json\n",
    "import os\n",
    "from typing import Any\n",
    "from langchain_core.tools import BaseTool\n",
    "from alibabacloud_cloudcontrol20220830.client import Client as cloudcontrol20220830Client\n",
    "from alibabacloud_tea_openapi import models as open_api_models\n",
    "from alibabacloud_cloudcontrol20220830 import models as cloudcontrol_20220830_models\n",
    "from alibabacloud_tea_util import models as util_models\n",
    "\n",
    "\n",
    "class AliyunResourceTool(BaseTool):\n",
    "    \"\"\"查询阿里云资源的工具\"\"\"\n",
    "\n",
    "    name: str = \"阿里云的云资源查询工具\"\n",
    "    description: str = (\n",
    "        \"用于查询账号下的阿里云的源信息，需要指通过 json 指定产品名 product、资源类型 resource、地域 region。\"\n",
    "        \"ECS 的默认资源为 Instance，VPC 的默认资源为 VPC。\"\n",
    "        \"region 只能是某一个指定的地域，参考格式：cn-hangzhou、cn-beijing、us-east-1\"\n",
    "    )\n",
    "\n",
    "    def _run(self, params) -> Any:\n",
    "        params_dict = json.loads(params)\n",
    "        request_path = f'/api/v1/providers/Aliyun/products/{params_dict[\"product\"]}/resources/{params_dict[\"resource\"]}'\n",
    "        get_resources_request = cloudcontrol_20220830_models.GetResourcesRequest(\n",
    "            region_id=params_dict.get(\"region\") or 'cn-hangzhou',\n",
    "            max_results=2\n",
    "        )\n",
    "        runtime = util_models.RuntimeOptions()\n",
    "        headers = {}\n",
    "        try:\n",
    "            config = open_api_models.Config(\n",
    "                access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],\n",
    "                access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']\n",
    "            )\n",
    "            # Endpoint 请参考 https://api.aliyun.com/product/cloudcontrol\n",
    "            config.endpoint = f'cloudcontrol.aliyuncs.com'\n",
    "            client = cloudcontrol20220830Client(config)\n",
    "            # 复制代码运行请自行打印 API 的返回值\n",
    "            result = client.get_resources_with_options(request_path, get_resources_request, headers, runtime)\n",
    "            return result.body\n",
    "        except Exception as error:\n",
    "            # 错误 message\n",
    "            print(error)\n",
    "            return '查询失败'\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2. 创建通义千问AGENT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义通义千问大模型AGENT\n",
    "\n",
    "# -*- coding: utf-8 -*-\n",
    "from langchain import hub\n",
    "from langchain.agents import AgentExecutor\n",
    "from langchain.agents import create_react_agent\n",
    "from langchain_community.llms import Tongyi\n",
    "\n",
    "class MyAgent():\n",
    "    def __init__(self):\n",
    "        self.agent_executor=self.assemble_agent_executor()\n",
    "\n",
    "    def assemble_agent_executor(self):\n",
    "        model = Tongyi()\n",
    "        model.model_name = 'qwen-max'\n",
    "        model.model_kwargs = {'temperature': 0.5}\n",
    "\n",
    "        tools = [\n",
    "            AliyunResourceTool(),\n",
    "        ]\n",
    "\n",
    "        prompt = hub.pull(\"hwchase17/react\")\n",
    "\n",
    "        agent = create_react_agent(model, tools, prompt)\n",
    "        agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\n",
    "        return agent_executor\n",
    "\n",
    "    def ask(self, question):\n",
    "        result = self.agent_executor.invoke({'input': question})\n",
    "        return result['output']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3. 阿里云资源查询\n",
    "\n",
    "下面我们尝试利用上述代码工具来查询阿里云资源，API应用[详情点击](https://api.aliyun.com/product/cloudcontrol?tab=apis)\n",
    "\n",
    "#### 2.3.1. 使用工具查询ECS资源\n",
    "首先测试Agent初始化是否成功，是否能查询“杭州的ECS实例信息”。本账号并没有关联ECS实例，所以查询结果为空。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m 需要使用阿里云的云资源查询工具来查询杭州地区（cn-hangzhou）的ECS实例到期时间。\n",
      "Action: 阿里云的云资源查询工具\n",
      "Action Input: {\n",
      "  \"product\": \"ECS\",\n",
      "  \"resource\": \"Instance\",\n",
      "  \"region\": \"cn-hangzhou\"\n",
      "}\u001b[0m'ALIBABA_CLOUD_ACCESS_KEY_ID'\n",
      "\u001b[36;1m\u001b[1;3m查询失败\u001b[0m"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "An output parsing error occurred. In order to pass this error back to the agent and have it try again, pass `handle_parsing_errors=True` to the AgentExecutor. This is the error: Could not parse LLM output: ` 由于查询失败，无法直接获取到杭州地区ECS实例的到期时间。通常情况下，查询失败可能由以下原因导致：\n\n1. **权限问题**：当前使用的账号可能没有足够的权限访问或查询该区域的ECS实例信息。\n2. **参数错误**：提供的产品名、资源类型或地域信息可能有误，需要核实输入数据的准确性。\n3. **网络问题**：与阿里云服务器之间的网络连接可能出现故障，导致查询请求无法送达或响应未返回。\n4. **服务异常**：阿里云的云资源查询工具本身可能存在临时性故障或维护状态。\n\n由于无法确定具体原因，我无法立即给出杭州地区ECS实例的到期时间。建议进行以下操作以解决问题：\n\n1. **检查账号权限**：确保当前使用的账号具有查询ECS实例信息的权限，如有必要，可联系账号管理员调整权限设置。\n2. **核实输入数据**：再次确认输入的JSON参数中产品名、资源类型和地域是否正确无误，特别是地域名称“cn-hangzhou”。\n3. **测试网络连接**：尝试访问其他阿里云服务或重新执行查询操作，以判断是否存在网络问题。\n4. **联系阿里云支持**：如果以上步骤均未能解决问题，建议联系阿里云官方技术支持，报告查询失败的情况，寻求专业帮助。\n\n在问题解决后，才能成功查询到杭州地区ECS实例的到期时间。因此，目前无法提供最终答案。`",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mOutputParserException\u001b[0m                     Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:1083\u001b[0m, in \u001b[0;36mAgentExecutor._iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1082\u001b[0m     \u001b[38;5;66;03m# Call the LLM to see what to do.\u001b[39;00m\n\u001b[0;32m-> 1083\u001b[0m     output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplan\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1084\u001b[0m \u001b[43m        \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1085\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m   1086\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1087\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1088\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m OutputParserException \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:386\u001b[0m, in \u001b[0;36mRunnableAgent.plan\u001b[0;34m(self, intermediate_steps, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m    385\u001b[0m inputs \u001b[38;5;241m=\u001b[39m {\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m{\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mintermediate_steps\u001b[39m\u001b[38;5;124m\"\u001b[39m: intermediate_steps}}\n\u001b[0;32m--> 386\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrunnable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcallbacks\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    387\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/runnables/base.py:1774\u001b[0m, in \u001b[0;36mRunnableSequence.invoke\u001b[0;34m(self, input, config)\u001b[0m\n\u001b[1;32m   1773\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m i, step \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msteps):\n\u001b[0;32m-> 1774\u001b[0m         \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstep\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1775\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1776\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;66;43;03m# mark each step as a child run\u001b[39;49;00m\n\u001b[1;32m   1777\u001b[0m \u001b[43m            \u001b[49m\u001b[43mpatch_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1778\u001b[0m \u001b[43m                \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43mf\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mseq:step:\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1779\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1780\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1781\u001b[0m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/output_parsers/base.py:176\u001b[0m, in \u001b[0;36mBaseOutputParser.invoke\u001b[0;34m(self, input, config)\u001b[0m\n\u001b[1;32m    175\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 176\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_with_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    177\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;28;43;01mlambda\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43minner_input\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mGeneration\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minner_input\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    178\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    179\u001b[0m \u001b[43m        \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    180\u001b[0m \u001b[43m        \u001b[49m\u001b[43mrun_type\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mparser\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    181\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/runnables/base.py:975\u001b[0m, in \u001b[0;36mRunnable._call_with_config\u001b[0;34m(self, func, input, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m    972\u001b[0m     context\u001b[38;5;241m.\u001b[39mrun(var_child_runnable_config\u001b[38;5;241m.\u001b[39mset, child_config)\n\u001b[1;32m    973\u001b[0m     output \u001b[38;5;241m=\u001b[39m cast(\n\u001b[1;32m    974\u001b[0m         Output,\n\u001b[0;32m--> 975\u001b[0m         \u001b[43mcontext\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    976\u001b[0m \u001b[43m            \u001b[49m\u001b[43mcall_func_with_variable_args\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    977\u001b[0m \u001b[43m            \u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m  \u001b[49m\u001b[38;5;66;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[1;32m    978\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m  \u001b[49m\u001b[38;5;66;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[1;32m    979\u001b[0m \u001b[43m            \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    980\u001b[0m \u001b[43m            \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    981\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    982\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m    983\u001b[0m     )\n\u001b[1;32m    984\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/runnables/config.py:323\u001b[0m, in \u001b[0;36mcall_func_with_variable_args\u001b[0;34m(func, input, config, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m    322\u001b[0m     kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m run_manager\n\u001b[0;32m--> 323\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/output_parsers/base.py:177\u001b[0m, in \u001b[0;36mBaseOutputParser.invoke.<locals>.<lambda>\u001b[0;34m(inner_input)\u001b[0m\n\u001b[1;32m    175\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    176\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_config(\n\u001b[0;32m--> 177\u001b[0m         \u001b[38;5;28;01mlambda\u001b[39;00m inner_input: \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mGeneration\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minner_input\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m    178\u001b[0m         \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m    179\u001b[0m         config,\n\u001b[1;32m    180\u001b[0m         run_type\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparser\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    181\u001b[0m     )\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain_core/output_parsers/base.py:219\u001b[0m, in \u001b[0;36mBaseOutputParser.parse_result\u001b[0;34m(self, result, partial)\u001b[0m\n\u001b[1;32m    207\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Parse a list of candidate model Generations into a specific format.\u001b[39;00m\n\u001b[1;32m    208\u001b[0m \n\u001b[1;32m    209\u001b[0m \u001b[38;5;124;03mThe return value is parsed from only the first Generation in the result, which\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    217\u001b[0m \u001b[38;5;124;03m    Structured output.\u001b[39;00m\n\u001b[1;32m    218\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m--> 219\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtext\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/output_parsers/react_single_input.py:75\u001b[0m, in \u001b[0;36mReActSingleInputOutputParser.parse\u001b[0;34m(self, text)\u001b[0m\n\u001b[1;32m     74\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m re\u001b[38;5;241m.\u001b[39msearch(\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAction\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124md*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*:[\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms]*(.*?)\u001b[39m\u001b[38;5;124m\"\u001b[39m, text, re\u001b[38;5;241m.\u001b[39mDOTALL):\n\u001b[0;32m---> 75\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m OutputParserException(\n\u001b[1;32m     76\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCould not parse LLM output: `\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtext\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m`\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m     77\u001b[0m         observation\u001b[38;5;241m=\u001b[39mMISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE,\n\u001b[1;32m     78\u001b[0m         llm_output\u001b[38;5;241m=\u001b[39mtext,\n\u001b[1;32m     79\u001b[0m         send_to_llm\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[1;32m     80\u001b[0m     )\n\u001b[1;32m     81\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m re\u001b[38;5;241m.\u001b[39msearch(\n\u001b[1;32m     82\u001b[0m     \u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m[\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms]*Action\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124md*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*Input\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124md*\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms*:[\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124ms]*(.*)\u001b[39m\u001b[38;5;124m\"\u001b[39m, text, re\u001b[38;5;241m.\u001b[39mDOTALL\n\u001b[1;32m     83\u001b[0m ):\n",
      "\u001b[0;31mOutputParserException\u001b[0m: Could not parse LLM output: ` 由于查询失败，无法直接获取到杭州地区ECS实例的到期时间。通常情况下，查询失败可能由以下原因导致：\n\n1. **权限问题**：当前使用的账号可能没有足够的权限访问或查询该区域的ECS实例信息。\n2. **参数错误**：提供的产品名、资源类型或地域信息可能有误，需要核实输入数据的准确性。\n3. **网络问题**：与阿里云服务器之间的网络连接可能出现故障，导致查询请求无法送达或响应未返回。\n4. **服务异常**：阿里云的云资源查询工具本身可能存在临时性故障或维护状态。\n\n由于无法确定具体原因，我无法立即给出杭州地区ECS实例的到期时间。建议进行以下操作以解决问题：\n\n1. **检查账号权限**：确保当前使用的账号具有查询ECS实例信息的权限，如有必要，可联系账号管理员调整权限设置。\n2. **核实输入数据**：再次确认输入的JSON参数中产品名、资源类型和地域是否正确无误，特别是地域名称“cn-hangzhou”。\n3. **测试网络连接**：尝试访问其他阿里云服务或重新执行查询操作，以判断是否存在网络问题。\n4. **联系阿里云支持**：如果以上步骤均未能解决问题，建议联系阿里云官方技术支持，报告查询失败的情况，寻求专业帮助。\n\n在问题解决后，才能成功查询到杭州地区ECS实例的到期时间。因此，目前无法提供最终答案。`",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[4], line 3\u001b[0m\n\u001b[1;32m      1\u001b[0m llm \u001b[38;5;241m=\u001b[39m MyAgent()\n\u001b[0;32m----> 3\u001b[0m \u001b[43mllm\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mask\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m杭州的ECS实例什么时候到期\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[3], line 29\u001b[0m, in \u001b[0;36mMyAgent.ask\u001b[0;34m(self, question)\u001b[0m\n\u001b[1;32m     28\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mask\u001b[39m(\u001b[38;5;28mself\u001b[39m, question):\n\u001b[0;32m---> 29\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43magent_executor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43minput\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mquestion\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m     30\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m result[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124moutput\u001b[39m\u001b[38;5;124m'\u001b[39m]\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/chains/base.py:162\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    160\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    161\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 162\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m    163\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m    164\u001b[0m final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m    165\u001b[0m     inputs, outputs, return_only_outputs\n\u001b[1;32m    166\u001b[0m )\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/chains/base.py:156\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    149\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m    150\u001b[0m     dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m    151\u001b[0m     inputs,\n\u001b[1;32m    152\u001b[0m     name\u001b[38;5;241m=\u001b[39mrun_name,\n\u001b[1;32m    153\u001b[0m )\n\u001b[1;32m    154\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    155\u001b[0m     outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 156\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    157\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m    158\u001b[0m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m    159\u001b[0m     )\n\u001b[1;32m    160\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    161\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:1329\u001b[0m, in \u001b[0;36mAgentExecutor._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m   1327\u001b[0m \u001b[38;5;66;03m# We now enter the agent loop (until it returns something).\u001b[39;00m\n\u001b[1;32m   1328\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_continue(iterations, time_elapsed):\n\u001b[0;32m-> 1329\u001b[0m     next_step_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1330\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1331\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1332\u001b[0m \u001b[43m        \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1333\u001b[0m \u001b[43m        \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1334\u001b[0m \u001b[43m        \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1335\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1336\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(next_step_output, AgentFinish):\n\u001b[1;32m   1337\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_return(\n\u001b[1;32m   1338\u001b[0m             next_step_output, intermediate_steps, run_manager\u001b[38;5;241m=\u001b[39mrun_manager\n\u001b[1;32m   1339\u001b[0m         )\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:1055\u001b[0m, in \u001b[0;36mAgentExecutor._take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1046\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m   1047\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m   1048\u001b[0m     name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m   1052\u001b[0m     run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m   1053\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m   1054\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1055\u001b[0m         [\n\u001b[1;32m   1056\u001b[0m             a\n\u001b[1;32m   1057\u001b[0m             \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iter_next_step(\n\u001b[1;32m   1058\u001b[0m                 name_to_tool_map,\n\u001b[1;32m   1059\u001b[0m                 color_mapping,\n\u001b[1;32m   1060\u001b[0m                 inputs,\n\u001b[1;32m   1061\u001b[0m                 intermediate_steps,\n\u001b[1;32m   1062\u001b[0m                 run_manager,\n\u001b[1;32m   1063\u001b[0m             )\n\u001b[1;32m   1064\u001b[0m         ]\n\u001b[1;32m   1065\u001b[0m     )\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:1055\u001b[0m, in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m   1046\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m   1047\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m   1048\u001b[0m     name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m   1052\u001b[0m     run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m   1053\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m   1054\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1055\u001b[0m         [\n\u001b[1;32m   1056\u001b[0m             a\n\u001b[1;32m   1057\u001b[0m             \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_iter_next_step(\n\u001b[1;32m   1058\u001b[0m                 name_to_tool_map,\n\u001b[1;32m   1059\u001b[0m                 color_mapping,\n\u001b[1;32m   1060\u001b[0m                 inputs,\n\u001b[1;32m   1061\u001b[0m                 intermediate_steps,\n\u001b[1;32m   1062\u001b[0m                 run_manager,\n\u001b[1;32m   1063\u001b[0m             )\n\u001b[1;32m   1064\u001b[0m         ]\n\u001b[1;32m   1065\u001b[0m     )\n",
      "File \u001b[0;32m~/miniconda3/envs/aiworld/lib/python3.9/site-packages/langchain/agents/agent.py:1094\u001b[0m, in \u001b[0;36mAgentExecutor._iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1092\u001b[0m     raise_error \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m   1093\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m raise_error:\n\u001b[0;32m-> 1094\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m   1095\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAn output parsing error occurred. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1096\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIn order to pass this error back to the agent and have it try \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1097\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124magain, pass `handle_parsing_errors=True` to the AgentExecutor. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1098\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis is the error: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mstr\u001b[39m(e)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1099\u001b[0m     )\n\u001b[1;32m   1100\u001b[0m text \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(e)\n\u001b[1;32m   1101\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandle_parsing_errors, \u001b[38;5;28mbool\u001b[39m):\n",
      "\u001b[0;31mValueError\u001b[0m: An output parsing error occurred. In order to pass this error back to the agent and have it try again, pass `handle_parsing_errors=True` to the AgentExecutor. This is the error: Could not parse LLM output: ` 由于查询失败，无法直接获取到杭州地区ECS实例的到期时间。通常情况下，查询失败可能由以下原因导致：\n\n1. **权限问题**：当前使用的账号可能没有足够的权限访问或查询该区域的ECS实例信息。\n2. **参数错误**：提供的产品名、资源类型或地域信息可能有误，需要核实输入数据的准确性。\n3. **网络问题**：与阿里云服务器之间的网络连接可能出现故障，导致查询请求无法送达或响应未返回。\n4. **服务异常**：阿里云的云资源查询工具本身可能存在临时性故障或维护状态。\n\n由于无法确定具体原因，我无法立即给出杭州地区ECS实例的到期时间。建议进行以下操作以解决问题：\n\n1. **检查账号权限**：确保当前使用的账号具有查询ECS实例信息的权限，如有必要，可联系账号管理员调整权限设置。\n2. **核实输入数据**：再次确认输入的JSON参数中产品名、资源类型和地域是否正确无误，特别是地域名称“cn-hangzhou”。\n3. **测试网络连接**：尝试访问其他阿里云服务或重新执行查询操作，以判断是否存在网络问题。\n4. **联系阿里云支持**：如果以上步骤均未能解决问题，建议联系阿里云官方技术支持，报告查询失败的情况，寻求专业帮助。\n\n在问题解决后，才能成功查询到杭州地区ECS实例的到期时间。因此，目前无法提供最终答案。`"
     ]
    }
   ],
   "source": [
    "llm = MyAgent()\n",
    "\n",
    "llm.ask(\"杭州的ECS实例什么时候到期\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于本章使用的测试账号没有开通ECS服务，因此反馈没有查询到ECS实例。\n",
    "\n",
    ">您可以[查看云服务产品信息](https://www.aliyun.com/product/ecs?source=5176.11533457#/)通过阿里云权益中心购买的 99 元/年的经济型 2核2G ECS 实例，新老客户都可以购买，并且后续可以 99 元续费。您可以参考[阿里云便宜服务器优惠合集](https://developer.aliyun.com/article/1445729)参与优惠活动\n",
    "\n",
    "#### 2.3.2. 查询更多阿里云资源\n",
    "\n",
    "接下来，我们在不做任何代码改动的情况下查询VPC信息。理论上我们可以查询[API应用范围](https://api.aliyun.com/product/cloudcontrol?tab=apis)的所有资源。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m 需要查询我在上海地区的VPC资源\n",
      "Action: 阿里云的云资源查询工具\n",
      "Action Input: {\"product\": \"VPC\", \"resource\": \"VPC\", \"region\": \"cn-shanghai\"}\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m{'maxResults': 2, 'requestId': '448C226E-CD30-5F33-BCA6-DCEE8794F8BD', 'resources': [], 'totalCount': 0}\u001b[0m\u001b[32;1m\u001b[1;3m 我现在知道最终答案\n",
      "Final Answer: 您在上海地区没有VPC资源。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'您在上海地区没有VPC资源。'"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm.ask(\"我在上海有没有VPC\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.3. 通义千问无需工具就能回答的问题\n",
    "\n",
    "最后，我们看看大模型是如何回答不在API范围内的问题的，这里我们将询问ECS的定价策略，通义千问能直接给出合理的答案。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m 我会回答。\n",
      "Final Answer: 阿里云ECS服务的定价主要基于以下几个因素：\n",
      "\n",
      "1. 实例类型：包括实例规格（如计算型c6、内存型r5等）、CPU核数、内存大小等。不同的实例类型性能配置不同，价格也会有所差异。\n",
      "\n",
      "2. 地域：同一实例在不同地域的价格可能会有所不同。\n",
      "\n",
      "3. 系统镜像：选择的操作系统类型和镜像版本也会影响定价，例如Windows镜像会比Linux镜像收费高一些。\n",
      "\n",
      "4. 存储类型与容量：ECS实例使用的数据盘类型（如高效云盘、SSD云盘、ESSD云盘等）及容量大小会影响价格。\n",
      "\n",
      "5. 计费方式：阿里云提供了按量付费（即按小时计费）和包年包月两种计费方式。按量付费模式下，您只需为实际使用的计算资源付费；包年包月则需要预先支付一定费用，一般情况下此种计费方式相比按量付费更为经济。\n",
      "\n",
      "6. 其他增值服务：如安全组、负载均衡、快照、备份等额外服务会产生额外费用。\n",
      "\n",
      "要获取准确的ECS实例定价信息，请访问阿里云官方产品页面或者使用阿里云官方提供的定价计算器进行详细计算：https://www.aliyun.com/price/product#/ecs 。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "ans = llm.ask(\"ECS服务如何定价\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.4. 封装成文件来执行\n",
    "\n",
    "上述代码我们封装在文件 aliyun_resource_agent.py 中，你可以使用如下的指令来执行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "问题：我在上海有没有VPC\n",
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m 需要查询用户在上海的VPC资源\n",
      "Action: 阿里云的云资源查询工具\n",
      "Action Input: {\"product\": \"VPC\", \"resource\": \"VPC\", \"region\": \"cn-shanghai\"}\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m{'maxResults': 2, 'requestId': '99B869A2-8F8C-53A8-AC0C-F53DD4571BC9', 'resources': [], 'totalCount': 0}\u001b[0m\u001b[32;1m\u001b[1;3m 根据查询结果，用户在上海没有VPC资源\n",
      "Final Answer: 您在上海没有VPC资源。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "您在上海没有VPC资源。\n"
     ]
    }
   ],
   "source": [
    "!python aliyun_resource_agent.py \"我在上海有没有VPC\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 参考资料\n",
    "- [阿里云控制API](https://api.aliyun.com/product/cloudcontrol?tab=apis)\n",
    "- [DashScope](https://dashscope.aliyun.com/)\n",
    "- [通义灵码](https://help.aliyun.com/document_detail/2590613.html)\n",
    "- [LangChain- 基于语义相似度的路由](https://python.langchain.com/docs/expression_language/cookbook/embedding_router)\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "chatllm",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
